// fillings for the toolbox header
#include "Includes.hpp" // includes for project
#include "Toolbox.hpp" // class declarations

enum MenuLevels menulvl;

void printMenu(MenuLevels menulvl) {
    switch(menulvl) {
    case FLOOR:
	cout << "\nCommand\tFunction"
	     << "\nN\tRegister new player, sport or division"
	     << "\nP\tPrint all or one Player to screen"
	     << "\nS\tPrint all or one Sport to screen"
	     << "\nC\tPrint sChedule to screen or file"
	     << "\nM\tPrint Match results from a given\n\t\tdate to screen or file"
	     << "\nT\tPrint Table"
	     << "\nF\tRead resultlist from File"
	     << "\nI\tPrint Info on an entire team to screen"
	     << "\nE\tEdit players on a given team"
	     << "\nR\tRemove player, sport or division"
	     << "\nQ\tQuit";
	break;
    case MAKENEW:
	cout << "\nCommand\tFunction"
	     << "\nP\tRegister new Player"
	     << "\nS\tRegister new Sport"
	     << "\nD\tRegister new Divilsion";
	break;
    case PRINTPLAYER:
	cout << "\nCommand\tFunction"
	     << "\nA\tPrint All players"
	     << "\n'number'\tPrint player with 'number'"
	     << "\n'name'\tPrint player with 'name'";
	break;
    case PRINTSPORT:
	cout << "\nCommand\tFunction"
	     << "\nA\tPrint All sports"
	     << "\n'name'\tPrint sport with 'name'";
	break;
    default: // this should not happen
	cout << "\n\t\tyou are doing it wrong!\n\t\tsee printmenu definition\n"; // print
	break;                                                                   // error
    }
}

////////////////////////////// WRITE TO FILE /////////////////////////
void writeToFile(Players* pplayers) {
    ofstream out("players.dta"); // open out file
    if (out.is_open()) { // if file-stream is open
	if (!(*pplayers).playersLlist->is_empty()) { // check if there is anything in list
	    Player* tempplayer; // make temporary player to work on
		out << pplayers->playersLlist->no_of_elements() << " #"; // write number of players to be printed
	    for (int plvar = 1; plvar <= pplayers->playersLlist->no_of_elements(); plvar++) {
		// if there is anything in the list
		tempplayer = (Player*)(*pplayers).playersLlist->remove_no(plvar); // pull
		// one from list
		tempplayer->writeToFile(&out); // call its 'writeToFile()'
		(*pplayers).playersLlist->add(tempplayer); // put it back into the list
	    } //for plvar end
	} else { // if 'playersLlist' is empty
	    cout << "\n\tthe player list is empty"; // print error
	} // if (!pplayers...is_empty()) end
    } else { // if file-stream is not open
	cout << "\n\tcould not open file\n"; // print error
    } // if (out.is_open()) end
} // 'wrightToFile(Players*)' end

void writeToFile(Sports* psports) { // write sports to file
    ofstream out("sports.dta"); // open out file
    if (out.is_open()) { // if file-stream is open
	if (!(*psports).sportsLlist->is_empty()) { // check if there is anything in list
	    Sport* tempsport; // make temporary sport to work on
	    out << (*psports).sportsLlist->no_of_elements() << " #";
	    for (int slvar = 1; slvar <= psports->sportsLlist->no_of_elements(); slvar++) {
		// if there is something in list
		tempsport = (Sport*)(*psports).sportsLlist->remove_no(slvar); // pull one out
		tempsport->writeToFile(&out); // call its 'writeToFile()'
		(*psports).sportsLlist->add(tempsport); // put it back in
	    } // for (slvar) end
	} else { // if list is empty
	    cout << "\n\tthe sports list is empty"; // print error
	} // if (!empty) end
    } else { // if file-stream is not open
	cout << "\n\tcould not open file"; // print error
    } // if (is_open()) end
} // function end

void writeToFile(Sport* psport) { // write divisions to file
    ofstream out("divisions.dta"); // open out file
    if (out.is_open()) { // if file-stream is open
	if (!(*psport).divisionLlist->is_empty()) { // check if there is anything in list
	    Division* tempdivision; // make temporary sport to work on
	    for (int dlvar = 1; dlvar <= psport->divisionLlist->no_of_elements(); dlvar++) {
		// if there is something in list
		tempdivision = (Division*)(*psport).divisionLlist->remove_no(dlvar); // pull
		// one out of list
		tempdivision->writeToFile(&out); // call its 'writeToFile()'
		(*psport).divisionLlist->add(tempdivision); // put it back in
	    } // for (dlvar) end
	} else { // if list is empty
	    cout << "\n\tthe division list is empty"; // print error
	} // if (!empty) end
    } else { // if file-stream is not open
	cout << "\n\tcould not open file"; // print error
    } // if (is_open()) end
} // function end

////////////////////////////// ITOA //////////////////////////////////
// the following function is not made by us,
// it is however in the public domain as far as i could find
/* The Itoa code is in the public domain */
char* Itoa(int value, char* str, int radix) {
    static char dig[] =
        "0123456789"
        "abcdefghijklmnopqrstuvwxyz";
    int n = 0, neg = 0;
    unsigned int v;
    char* p, *q;
    char c;
    
    if (radix == 10 && value < 0) {
        value = -value;
        neg = 1;
    }
    v = value;
    do {
        str[n++] = dig[v%radix];
        v /= radix;
    } while (v);
    if (neg)
        str[n++] = '-';
    str[n] = '\0';
    
    for (p = str, q = p + (n-1); p < q; ++p, --q)
        c = *p, *p = *q, *q = c;
    return str;
}
// this code is not our work, the itoa code is as
// stated by the author in the public domain




void displaytp() { // display players on a given team
    
    Sport* tempsport = NULL;
    Division* tempdiv = NULL;
//    Team* tempTeam = NULL;
    char* tempname;
    char* tempdivname;
    char* tempteamname;
    
    
    tempname = robio.readName("sport"); // read a sports name
    if(sports.sportsLlist->in_list(tempname)) { // check if it exists
	tempsport = (Sport*)sports.sportsLlist->remove(tempname); // remove it if it does
	
	
	tempdivname = robio.readName("division"); // read a division name
	if((*tempsport).divisionLlist->in_list(tempdivname)) { // check if it exists
	    tempdiv = (Division*)tempsport->divisionLlist->remove(tempdivname); // remove it if it does
	    
	    
	    
	    tempteamname = robio.readName("Team"); // read team name
	    for(int lvar = tempdiv->teamcount; lvar >= 0; lvar--) { // go through list of teams
		if (strcmp( (*tempdiv).teamsarr[lvar]->getName(), tempteamname)) { // check if current team is 
		    // the one we are looking for
		    tempdiv->teamsarr[lvar]->display(); // display team if it is
		}		
	    }	    
	}
	else{ // print error
	    cout << "Division does not exist in the list";
	}		
    }
    else{ // print error
        cout << "Sport does not exist in the list";   
    } 
}

void changepl() {         //Takes a player out or puts one in to an array
    
    Sport* tempsport = NULL;
    Division* tempdiv = NULL;
    Team* tempteam = NULL;
    char* tempname;
    char* tempdivname;
    char* tempteamname;
    int tempplayernum = NULL;
    bool found = false;
    
    tempname = robio.readName("sport");               //Asks for a sport and checks if it exists
    if(sports.sportsLlist->in_list(tempname)) {
	tempsport = (Sport*)sports.sportsLlist->remove(tempname);
	
	
	tempdivname = robio.readName("division");         //Asks for a division and checks if it exists
	if((*tempsport).divisionLlist->in_list(tempdivname)) {
	    tempdiv = (Division*)tempsport->divisionLlist->remove(tempdivname);
	    
	    
	    
	    tempteamname = robio.readName("Team");       //Asks for a team and checks if it exists
	    for(int lvar = tempdiv->teamcount; lvar >= 0; lvar--) {
		if (strcmp( (*tempdiv).teamsarr[lvar]->getName(), tempteamname)) {
		    tempteam = tempdiv->teamsarr[lvar];
		    //If the above things exist, then the user chooses to either remove or add a player
		    tempplayernum = players.getPlayer(robio.readName("player to change")); // get player num
		    int answer = robio.readInt("do you want to add[1] or delete[0] player", 1); 
                    
		    if(answer) {  //This adds a player to the array
			for(int pvar = tempteam->playercount; pvar >= 0; pvar--) { // go through all players
			    if (tempteam->playersid[pvar] == tempplayernum) {
				found = true;
			    }
			}
			if (!found) {
			    tempteam->playersid[tempteam->playercount+1] = tempplayernum;
			    tempteam->playercount++;
			} else {
			    cout << "\nplayer number " << tempplayernum << " is already on team"; // print error
			}
		    } else {  //This removes a player from the array
			for(int pvar = tempteam->playercount; pvar >= 0; pvar--) {
			    if (tempteam->playersid[pvar] == tempplayernum) {
				tempteam->playersid[pvar] = NULL;
				tempteam->playercount--;
			    }
			    else {
				cout << "The playernr does not exist";
			    }
			} // for pvar end
		    }
		}
	    }  // for lvar end
	}      //These are in case sport, division or team does not exist
	else{
	    cout << "\n\tDoes not exist in the list 'changepl'";
	}
    }
    else{
	cout << "\n\tDoes not exist in the list 'changepl'";
    }
} // function end



void readFromFile() {
    ifstream playerin("players.dta"); // open file-stream 'players.dta'
    int numplayers; // number of players to be read
    unsigned int tempnum = 0; // make a number to read player number into temporary
    Player* tempplayer; // make a pointer to player
    
    if (playerin.is_open()) { // check if file-stream is open
	playerin >> numplayers; // read how many players are supposed to be on this line
	playerin.ignore(2, '#'); // ignore and extract up til the hash char
	if (numplayers > 0) {
	    for (int pvar = 0; pvar <= numplayers; pvar++) {
//		while (!playerin.eof()) { // checks for end of file
		playerin >> tempnum; // read player number
		playerin.ignore(2, '#'); // ignore and extract up til the hash char
		tempplayer = new Player(&playerin, tempnum); // make new player, read from file
		players.addPlayer(tempplayer, 0); // add the new player to list
	    } // for pvar end // while end
	    players.uniqueIdInit(); // initialize players unique id
	} else { // if there are no players in file
	    cout << "\n\tthere are no players in 'players.dta'"; // print error
	}
	playerin.close(); // close file-stream
    } else { // if file-stream is not open
	cout << "\n\tcould not open 'players.dta'"; // print error
    } // if file-stream is open end
    
    ifstream sportin("sports.dta"); // open file-stream 'sports.dta'
    Sport* tempsport; // make a temporary sport
    char* tempname = NULL; // and a temporary name
    if (sportin.is_open()) { // if file-stream is open
	int numsports;
	sportin >> numsports; sportin.ignore(2, '#'); // read numsports, ignore delimiter
	if (numsports > 0) {
	    for (int nsvar = 0; nsvar <= numsports; nsvar++) {
//	    while (!sportin.eof()) { // do this till end of file
		tempname = robio.readFileString(&sportin); // read temporary name
		sportin.ignore(2, '#'); // ignore and extract up til the hash char
		tempsport = new Sport(&sportin, tempname); // make new sport read from file-stream
		// add tempsport to sportsLlist
	    } // for end ////// // while end
	} else {
	    cout << "\n\tthere are no sports in 'sports.dta'"; // print error
	}
	sportin.close(); // close file-stream
    } else { // if file-stream is not open
	cout << "\n\tcould not open sports.dta"; // print error
    }
}

void printWriteTable() {
	Sport* tempsport = (Sport*)sports.sportsLlist->remove(robio.readName("sport")); // pull a sport from lis
	char* divname = robio.readName("division"); // read division nam
	char* filename = robio.readFileName("filename", NULL, 0); // read file nam
	if (strlen(filename) == 0) {
	    tempsport->printWriteTable(&cout, divname);
	} else {
	    ofstream out(filename);
	    tempsport->printWriteTable(&out, divname); // print/write table to screen/fil
	
	sports.sportsLlist->add(tempsport); // put sport back into list
	}
}

void selectionSortTable(Table* tables) { // puts biggest first
	int arrlength = MAXTEAMS;
    Table* biggest = NULL; // biggest of the elements to be sorted
    for (int svar = 0; svar < arrlength - 1; svar++) { // go through elements
		(*biggest) = tables[svar]; // set 'biggest' to start of elements
		for (int index = svar + 1; index < arrlength; index++) { // go through "subarray" of elements
			if (tables[index].points > biggest->points) { // if 'index' is bigger than 'biggest'
				(*biggest) = tables[index]; // then biggest is index
		    } // if sortarr < sortarr end
		} // for index end
		Table* container = NULL;
		(*container) = tables[svar];
		tables[svar] = (*biggest);
		biggest = container;
    } // for svar end
} // function end

void selectionSortAsc(int* const sortarr, const int arrlength) { // puts smallest first
    int smallest; // smallest of the elements to be sorted
    for (int svar = 0; svar < arrlength - 1; svar++) { // go through elements
	smallest = svar; // set 'smallest' to start of elements
	for (int index = svar + 1; index < arrlength; index++) { // go through "subarray" of elements
	    if (sortarr[index] < sortarr[smallest]) { // if 'index' is smaller than 'smallest'
		smallest = index; // then smallest is index
	    } // if sortarr < sortarr end
	} // for index end
	swap(&sortarr[svar], &sortarr[smallest]); // put smallest in correct place
    } // for svar end
} // function end

void selectionSortDesc(int* const sortarr, const int arrlength) { // puts biggest first
    int biggest; // biggest of the elements to be sorted
    for (int svar = 0; svar < arrlength - 1; svar++) { // go through elements
	biggest = svar; // set 'biggest' to start of elements
	for (int index = svar + 1; index < arrlength; index++) { // go through "subarray" of elements
	    if (sortarr[index] > sortarr[biggest]) { // if 'index' is bigger than 'biggest'
		biggest = index; // then biggest is index
	    } // if sortarr < sortarr end
	} // for index end
	swap(&sortarr[svar], &sortarr[biggest]); // put biggest in correct place
    } // for svar end
} // function end

void swap(int* const swapvar1, int* const swapvar2) {
    int container = (*swapvar1); // keep swapvar1
    (*swapvar1) = (*swapvar2); // swap var 1 with var 2
    (*swapvar2) = container; // put former swapvar1 into current swapvar2
} // and done swapping

void printWriteMatchResults() {
    Sport* tempsport = NULL;
    Division* tempdiv = NULL;
//    Team* tempTeam = NULL;
    char* tempname;
    char* tempdivname;
    char* tempfilename;
    char* tempdate = NULL;
    
    tempname = robio.readName("sport"); // read a sports name
    if(sports.sportsLlist->in_list(tempname)) { // check if it exists
	tempsport = (Sport*)sports.sportsLlist->remove(tempname); // remove it if it does
	
	
	tempdivname = robio.readName("division (can be left blank)"); // read a division name
	if((*tempsport).divisionLlist->in_list(tempdivname)) { // check if it exists
	    tempdiv = (Division*)tempsport->divisionLlist->remove(tempdivname); // remove it if it does
	    
	    tempfilename = robio.readName("File (can be left blank)"); // read team name
	    
	    int tempaar = robio.readInt("year (yyyymmdd)", 20123012, 19900101);
	    Itoa(tempaar, tempdate, 10);
	    if(strlen(tempfilename) == 0) {
		for (int svard = 0; svard <= tempdiv->teamcount; svard++) { // go through schedule downways
		    for (int svars = 0; svars <= tempdiv->teamcount; svars++) { // go through schedule sideways
			if( strcmp((*tempdiv->schedule[svard][svars]).date, tempdate) == 0) {
			    cout << (*tempdiv->schedule[svard][svars]).date << ' ' << (*tempdiv->schedule[svard][svars]).homegoals
				 << ' ' << (*tempdiv->schedule[svard][svars]).awaygoals 
				 << ' ' << (*tempdiv->schedule[svard][svars]).normalplaytime;
			    for (int hsvar = 0; hsvar <= (*tempdiv->schedule[svard][svars]).homegoals; hsvar++) {
				cout << (*tempdiv->schedule[svard][svars]).homescorers[hsvar] << ' ';
			    } // for hsvar end
			    for (int asvar = 0; asvar <= (*tempdiv->schedule[svard][svars]).awaygoals; asvar++) {
				cout << (*tempdiv->schedule[svard][svars]).awayscorers[asvar] << ' ';
			    } // for asvar end
			}
		    } // for svars end
		    cout << endl;
		} // for svard end
	    } else {
		ofstream out(tempfilename);
		if (out.is_open()) {
		    for (int svard = 0; svard <= tempdiv->teamcount; svard++) { // go through schedule downways
			for (int svars = 0; svars <= tempdiv->teamcount; svars++) { // go through schedule sideways
			    if( strcmp((*tempdiv->schedule[svard][svars]).date, tempdate) == 0) 
				(*tempdiv->schedule[svard][svars]).writeToFile(&out); // write itself to file
			} // for svars end
			(out) << endl; // start writing the next line
		    } // for svard end
		    out.close();
		} else cout << "Unable to open file";
	    }
	}
    }
}

void readResults(ifstream* in) {
    if(in) { 
	char* tempdivname, *tempsportname;
	tempdivname = robio.readFileString(in);
	tempsportname = robio.readFileString(in);
	Sport* tempsport = (Sport*)sports.sportsLlist->remove(tempsportname);
	Division* tempdiv = (Division*)tempsport->divisionLlist->remove(tempdivname);
	for (int svard = tempdiv->teamcount; svard <= MAXTEAMS; svard++) {
	    for (int svars = tempdiv->teamcount; svars <= MAXTEAMS; svars++) {
		tempdiv->schedule[svard][svars] = new Result(in);
	    }
	}
    }
}
